Getting started
###############

Genode can be approached from two different angles: as an operating-system
architecture or as a practical tool kit. This chapter assists you with
exploring Genode as the latter. After introducing the recommended
development environment,
it guides you through the steps needed to obtain the source code
(Section [Obtaining the source code]), to use the tool chain
(Section [Using the build system]), to test-drive system scenarios
(Section [A simple system scenario]), and to create your first custom
component from scratch (Section [Hello world]).


Recommended development environment
-----------------------------------

Genode is regularity used and developed on GNU/Linux. It is recommended to
use the latest long-term support (LTS) version of Ubuntu. Make sure that your
installation satisfies the following requirements:

* GNU Make version 3.81 (or newer) needed by the build system,
* _libSDL-dev_ needed to run system scenarios directly on Linux,
* _tclsh_ and _expect_ needed by test-automation and work-flow tools,
* _qemu_ and _genisoimage_ needed for testing system scenarios on non-Linux
  platforms via the Qemu emulator.

For using the entire collection of ported 3rd-party software, the following
packages should be installed additionally:
_byacc_, _autoconf2.64_, _autogen_, _bison_, _flex_, _g++_, _git_, _gperf_,
_libxml2-utils_, _subversion_, and _xsltproc_.


Seeking help
------------

The best way to get assistance while exploring Genode is to consult the
mailing list, which is the primary communication medium of regular
users and developers alike. Please feel welcome to join in!

:Mailing Lists:

  [http://genode.org/community/mailing-lists]

If you encounter a new bug, ambiguous documentation, or a missing feature,
please consider opening a corresponding issue at the issue tracker:

:Issue tracker:

  [https://github.com/genodelabs/genode/issues]


Obtaining the source code
=========================

The centerpiece of Genode is the source code found within the official Git
repository:

:Source code at GitHub:

  [https://github.com/genodelabs/genode]

To obtain the source code, clone the Git repository:

! git clone https://github.com/genodelabs/genode.git

After cloning, you can find the source code within
the _genode/_ directory. In the following, we refer to this directory
as _<genode-dir>_.


Source-tree structure
=====================

Top-level directory
-------------------

At the root of the directory tree, there is the following content:

:_doc/_: Documentation in plain text format, including the
  release notes
  of all versions. _Practical hint:_ The comprehensive release notes
  conserve most of the hands-on documentation aggregated over the lifetime
  of the project. When curios about a certain topic, it is often worthwhile to
  "grep" for the topic within the release notes to get a starting point
  for investigation.

:_tool/_: Tools and scripts to support the build system, various boot loaders,
  the tool chain, and the management of 3rd-party source code. Please find
  more information in the _README_ file contained in the subdirectory.

:_repos/_: The so-called source-code repositories, which contain the actual
  source code of the framework components. The source code is not organized
  within a single source tree but multiple trees. Each tree is called a
  _source-code repository_ and has the same principle structure.
  At build time, a set of source-code repositories can be selected to be
  incorporated into the build process. Thereby, the source-code repositories
  provide a coarse-grained modularization of the framework.


Repositories overview
---------------------

The _<genode-dir>/repos/_ directory contains the following source-code
repositories.

:_base/_:

  The fundamental framework interfaces as well as the platform-agnostic parts
  of the core component (Section [Core - the root of the component tree]).

:_base-<platform>/_:
  Platform-specific supplements of the _base/_ repository where _<platform>_
  corresponds to one of the following:

  :_linux_:

    Linux kernel (both x86_32 and x86_64).

  :_nova_:

    NOVA microhypervisor.
    More information about the NOVA platform is provided by Section
    [Execution on the NOVA microhypervisor (base-nova)].

  :_hw_:

    The hw platform allows the execution of Genode on bare ARM hardware
    without the need for a separate kernel. The kernel functionality is
    included in the core component. More information about the hw platform
    can be found in Section [Execution on bare hardware (base-hw)].

  :_foc_:

    Fiasco.OC is a modernized version of the L4/Fiasco microkernel with a
    completely revised kernel interface fostering capability-based
    security.

  :_okl4_:

    OKL4 kernel originally developed at Open-Kernel-Labs.

  :_pistachio_:

    L4ka::Pistachio kernel developed at University of Karlsruhe.

  :_fiasco_:

    L4/Fiasco kernel originally developed at University of Technology Dresden.

  :_codezero_:

    Codezero microkernel originally developed by B-Labs.

:_os/_:

  OS components such as the init component, device drivers, and basic system
  services.

:_demo/_:

  Various services and applications used for demonstration purposes, for
  example the graphical application launcher and the tutorial browser
  described in Section [A simple system scenario] can be found here.

:_hello_tutorial/_:

  Tutorial for creating a simple client-server scenario. This
  repository includes documentation and the complete source code.

:_libports/_:

  Ports of popular open-source libraries, most importantly the C library.
  Among the 3rd-party libraries are Qt5, libSDL, freetype, Python, ncurses,
  Mesa, and libav.

:_dde_linux/_:

  Device-driver environment for executing Linux kernel subsystems as
  user-level components. Among the subsystems are the USB stack, the
  Intel wireless stack, and the TCP/IP stack.

:_dde_ipxe/_:

  Device-driver environment for executing network drivers of the iPXE project.

:_dde_oss/_:

  Device-driver environment for the audio drivers of the Open Sound System.

:_dde_rump/_:

  Port of rump kernels, which are used to execute subsystems of the NetBSD
  kernel as user-level components.
  The repository contains a server that uses a rump kernel to provide
  various NetBSD file systems.

:_ports/_:

  Ports of 3rd-party applications.

:_ports-<platform>/_:

  These platform-specific source-code repositories contain software that
  capitalizes special features of the respective kernel platform.
  For the Fiasco.OC platform, 'ports-foc' hosts a port of the L4Linux
  kernel.

:_gems/_:

  Components that use
  both native Genode interfaces as well as features of other high-level
  repositories, in particular shared libraries provided by _libports/_.


Using the build system
======================

Genode relies on a custom tool chain, which can be downloaded at the following
website:

:Tool chain:

  [http://genode.org/download/tool-chain]


Build directory
---------------

The build system never touches the source tree but generates object
files, libraries, and programs in a dedicated build directory. We do not have a
build directory yet. For a quick start, let us create one using the following
command:

! cd <genode-dir>
! ./tool/create_builddir linux_x86

The command creates a new build directory at 'build/linux_x86'. The build
directory is readily configured for using GNU/Linux as base platform.


Build configuration
-------------------

Before using the build directory, it is recommended to revisit and
possibly adjust the build configuration, which is located in the
_etc/_ subdirectory of the build directory, e.g., _build/linux_x86/etc/_.
The _build.conf_ file contains global build parameters, in particular
the selection of source-code repositories to be incorporated. It is also
a suitable place for adding global build options. For example, for
enabling GNU make to use 4 CPU cores, add the following line to the
_build.conf_ file:

! MAKE += -j4


Building components
-------------------

The recipe for building a component has the form of a _target.mk_ file
within the _src/_ directory of one of the source-code repositories.
For example, the _target.mk_ file of the init component is located
at _<genode-dir>/repos/os/src/init/target.mk_. To build the component, execute
the following command from within the build directory:

! make init

The argument "init" refers to the path relative to the _src/_ subdirectory.
The build system determines and builds all targets found under this path in
all source-code repositories.
When the build the is finished, the resulting executable binary can be found
in a subdirectory that matches the target's path. Additionally, the build
system installs a symbolic link in the _bin/_ subdirectory that points to the
executable binary.

If the specified path contains multiple _target.mk_ files in different
subdirectories, the build system builds all of them. For example, the
following command builds all targets found within one of the
_<repo>/src/drivers/_ subdirectories:

! make drivers

Furthermore, it is possible to specify multiple targets at once. The following
command builds both the init component and the timer driver:

! make init drivers/timer


A simple system scenario
========================

The build directory offers much more than an environment for building
components. It supports the automation of system-integration work flows,
which typically include the following steps:

# Building a set of components,
# Configuring the static part of a system scenario,
# Assembling a boot directory with all ingredients needed by the scenario,
# Creating a boot image that can be loaded onto the target platform,
# Booting the target platform with the boot image,
# Validating the behaviour of the scenario.

The recipe for such a sequence of steps can be expressed in the form of
a so-called run script. Each run script represents a system scenario and
entails all information required to reproduce the scenario. Run scripts can
reside within the _run/_ subdirectory of any source-code repository.

Genode comes with a ready-to-use run script showcasing simple graphical demo
scenario. It is located at _<genode-dir>/repos/os/run/demo.run_ and can
be executed from within the build directory via:

! make run/demo

The command will lookup a run script called _demo.run_ in all repositories
listed in _etc/build.conf_. It will eventually find the run script within
the _os/_ repository. After completing the build of all components needed,
the command will then automatically start the scenario.
Because the build directory was created for the _linux_x86_ platform, the
scenario
will be executed directly on the host system where each Genode component
resides in a distinct Linux process. To explore the scenario, follow the
instructions given by the graphical tutorial browser.

The terminal where the 'make run/demo' command was issued displays the log
output of the Genode system. To cancel the execution,
hit _control-c_ in the terminal.


Targeting a microkernel
-----------------------

Whereas the ability to run system scenarios on top of Linux allows for the
convenient and rapid development of components and protocols, Genode is
primarily designed for the use of microkernels. The choice of the microkernel
to use is up to the user of the framework and may depend on various factors
like the feature set, the supported hardware architectures, the license, or
the development community. To execute the demo scenario directly on the NOVA
microhypervisor, the following preparatory steps are needed:

# Download the 3rd-party source code of the NOVA microhypervisor
  ! <genode-dir>/tool/ports/prepare_port nova

  The _prepare_port_ tool downloads the source code of NOVA to a
  subdirectory at _<genode-dir>/contrib/nova-<hash>/_ where _<hash_
  uniquely refers to the prepared version of NOVA.

# On real hardware, the scenario needs a framebuffer driver. The VESA
  driver relies on a 3rd-party x86-emulation library in order to execute
  the VESA BIOS code. Download the 3rd-party source code of the _x86emu_
  library:
  ! <genode-dir>/tool/ports/prepare_port x86emu

  The source code will be downloaded to _<genode-dir>/contrib/x86emu-<hash>/_.

# Create a build directory for the _nova_x86_64_ platform:
  ! <genode-dir>/tool/create_builddir nova_x86_64

  This step creates a new build directory at _<genode-dir>/build/nova_x86_64_.

# Adjust the build configuration by editing the file _etc/build.conf_
  within the just-created build directory.
  Apart from enabling the parallelization of the build process as
  mentioned in Section [Using the build system], we need to incorporate
  the _libports_ source-code repository into the build process by uncommenting
  the corresponding line in the configuration. Otherwise the build system
  would fail to build the VESA driver, which resides within _libports/_.

With those preparations in place, issue the execution of the demo run
script from within the build directory:

! cd <genode-dir>/build/nova_x86_64
! make run/demo

This time, an instance of Qemu will be started to execute the demo scenario.
The Qemu command-line arguments appear in the log output. As suggested
by the arguments, the scenario is supplied to Qemu as an ISO image residing
at _var/run/demo.iso_. This ISO image can not only be used with Qemu but
also with a real machine. For example, creating a bootable USB stick with
the system scenario is as simple as writing the ISO image onto an USB stick:
! sudo dd if=var/run/demo.iso of=/dev/<usb-device> bs=8M conv=fsync

Note that _<usb-device>_ refers to the device node of an USB stick. It can be
determined using the 'dmesg' command after plugging-in the USB stick.
For booting from the USB stick, you may need to adjust the BIOS
settings of the test machine accordingly.


Hello world
===========

This section introduces the steps needed to create and execute a simple
custom component that prints a hello-world message.


Using a custom source-code repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In principle, it would be possible to add a new component to one of the
existing source-code repositories found at _<genode-dir>/repos/_. However,
unless the component is meant to be incorporated into upstream development
of the Genode project, it is generally recommended to keep custom code
separate from Genode's code base. This eases future updates to new versions
of Genode and allows you to pick a revision-control system of your choice.

The new repository must appear within the _<genode-dir>/repos/_ directory.
This can be achieved by either hosting it as a subdirectory or by creating
a symbolic link that points to an arbitrary location of your choice. For
now, let us host a new source-code repository called "lab" directly within
the _repos/_ directory.

! cd <genode-dir>
! mkdir repos/lab

The lab repository will contain the source code and build rules for a
single component as well as a run script for executing the component within
Genode. Component source code reside in a _src/_ subdirectory. By convention,
the _src/_ directory contains further subdirectories for hosting different
types of components, in particular _server_ (services and protocol stacks),
_driver_ (hardware-device drivers), and _app_ (applications). For the
hello-world component, an appropriate location would be _src/app/hello/_:

! mkdir -p repos/lab/src/app/hello


Source code and build description
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The _hello/_ directory contains both the source code and the build description
of the component. The main part of each component typically resides in a
file called _main.cc_. Hence, for a hello-world program, we have to create
the _repos/lab/src/app/hello/main.cc_ file with the following content:

! #include <base/printf.h>
!
! int main()
! {
!   Genode::printf("Hello world\n");
!   return 0;
! }

For C and C++ programmers, the program is self-explanatory. Still, the
'printf' function deserves an explanation. This function is not provided by
a C library. In fact, the simple hello-world component will be built
with no C library at all. It will solely incorporate the low-complexity
base libraries of the Genode framework. The 'Genode::printf' function is
a small and very rigid output facility, which covers not more than the
limited use cases present in low-level Genode components. Of course,
for higher-level applications where low complexity is not a concern, the
optional C and C++ standard libraries are available.

Please note that there exists a recommended coding style for genuine Genode
components. If you consider submitting your work to the upstream development
of the project, please pay attention to these common guidelines.

:Coding-style guidelines:

  http://genode.org/documentation/developer-resources/coding_style

The source file _main.cc_ is accompanied by a build-description file called
_target.mk_. It contains the declarations for the source files, the libraries
used by the component, and the name of the component. Create the file
_repos/lab/src/app/hello/target.mk_ with the following content:

! TARGET = hello
! SRC_CC = main.cc
! LIBS  += base


Building the component
~~~~~~~~~~~~~~~~~~~~~~

With the build-description file in place, it is time to build the new
component, for example from within the _linux_x86_ build directory as
created in Section [A simple system scenario]. To aid the build system
to find the component, we have to extend the build
configuration _<build-dir>/etc/build.conf_ by appending the following line:

! REPOSITORIES += $(GENODE_DIR)/repos/lab

By adding this line, the build system will consider our custom source-code
repository. To build the component, issue the following command:

! make app/hello

This step builds the base libraries of the framework, compiles the _main.cc_
file and links the executable ELF binary called "hello". The result can be
found in the _<build-dir>/app/hello/_ subdirectory.


Defining a system scenario
~~~~~~~~~~~~~~~~~~~~~~~~~~

For testing the component, we need to define a system scenario that
incorporates the component. As mentioned in
Section [A simple system scenario], such a description has the form of
a run script. To equip the _lab_ repository with a run script, we first
need to create a _lab/run/_ subdirectory:

! mkdir <genode-dir>/repos/lab/run

Within this directory, we create the file
_<genode-dir>/repos/lab/run/hello.run_ with the following content:

!build "core init app/hello"
!create_boot_directory
!install_config {
! <config>
!   <parent-provides>
!     <service name="LOG"/>
!     <service name="RM"/>
!   </parent-provides>
!   <default-route>
!     <any-service> <parent/> </any-service>
!   </default-route>
!   <start name="hello">
!     <resource name="RAM" quantum="10M"/>
!   </start>
! </config>
!}
!build_boot_image "core init hello"
!append qemu_args "-nographic -m 64"
!run_genode_until {child "hello" exited with exit value 0} 10

This run script performs the following steps:

# It builds the components core, init, and app/hello.
; XXX references to the Sections about core and init

# It creates a fresh boot directory at _<build-dir>/var/run/hello_.
  This directory contains all files that will end up in the final
  boot image.

# It creates a configuration for the init component. The configuration
  starts the hello component as the only child of init. Session
  requests originating from the hello component will always be directed
  towards the parent of init, which is core.

# It assembles a boot image with the executable ELF binaries core,
  init, and hello. The binaries are picked up from the _<build-dir>/bin/_
  subdirectory.

# It instructs Qemu (if used) to disable the graphical output.

# It triggers the execution of the system scenario and watches the log
  output for the given regular expression. The execution ends when
  the log output appears or after a timeout of 10 seconds.

The run script can be executed from within the build directory via the
command:

! make run/hello

After the boot output of the used kernel, the scenario will produce the
following output:

! [init -> hello] Hello world
! [init] virtual void Genode::Child_policy::exit(int):
!        child "hello" exited with exit value 0
! Run script execution successful.

The label within the brackets at the start of each line identifies the
component where the message originated from. The final line is printed by the
run tool after it successfully matched the log output against the regular
expression specified to the 'run_genode_until' command.

